/*
 * INSANE - Interactive Structural Analysis Environment
 *
 * Copyright (C) 2003-2005
 * Universidade Federal de Minas Gerais
 * Escola de Engenharia
 * Departamento de Engenharia de Estruturas
 * 
 * Author's email :    insane@dees.ufmg.br
 * Author's website :  http://www.dees.ufmg.br/insane
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package br.ufmg.dees.insane.draw;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.util.ArrayList;
import java.util.Vector;

public class FaceDraw extends Draw {
	
	private Polygon shape;
	private ArrayList points;
	private boolean isBoundaryOn = true;
	private boolean isFillOn = false;
	public static final byte NONE = 1;
	public static final byte TRANSPARENT = 2;
	public static final byte OPAQUE	= 3;
	private byte fillType = 2;
	private float intensity = 0.5f;
	private Float lineWidth = 1.5f;
	private Color faceColor = Color.YELLOW;
	private Color fillColor = Color.RED;
	
//	*****************************************************************************
	
	public FaceDraw() {
		this.points = new ArrayList();
	}
	
	public FaceDraw(ArrayList points) {
		this.points = new ArrayList();
		this.points = points;
	}
	
	public FaceDraw(ArrayList points, Object represents) {
		this.points = new ArrayList();
		this.points = points;
		this.setRepresents(represents);
	}
	
//	*****************************************************************************
	
	public boolean equals(Object obj) {
		
		return false;
	}
	
//	*****************************************************************************
	
	public Vector<Object> getShapes() {
		return null;
	}
	
//	*****************************************************************************
	
	public double getAngle() {
		double theta=0.0;
		
		return theta;
	}
	
//	*****************************************************************************
	
	/**
	 * Draws in a given Graphics.
	 *
	 * @see   java.awt.Graphics
	 */
	public void draw(Graphics2D g2) {
		shape = new Polygon();
		LineDraw line = new LineDraw();
		
		for(int j=0;j<points.size();j++){
			((Polygon)shape).addPoint( ((Point)points.get(j)).x, ((Point)points.get(j)).y );
			//g2.setStroke(new BasicStroke(lineWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
			//g2.setColor(faceColor);
			//g2.draw(shape);
		}
		
			switch (this.fillType){
			case NONE:{
				break;
			}
			case TRANSPARENT:{
				Color color = this.fillColor;
				float red = (color.getRed()/255f);
				float green = (color.getGreen()/255f);
				float blue = (color.getBlue()/255f);
				Color trans = new Color(red,green,blue,intensity);
				g2.setPaint(trans);
				g2.setStroke(new BasicStroke(0.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
				g2.fill(shape);
				break;
			}
			case OPAQUE:{
				Color color = this.fillColor;
				g2.setPaint(color);
				g2.fill(shape);
				break;
			}
			}
		if(isBoundaryOn){
			g2.setStroke(new BasicStroke(lineWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
			g2.setColor(faceColor);
			for(int i=0;i<this.points.size();i++){
				if(i!=this.points.size()-1){
					line = new LineDraw ((Point)points.get(i),(Point)points.get(i+1));
				}else if(i==this.points.size()-1){
					line = new LineDraw ((Point)points.get(i),(Point)points.get(0));
				}
				line.draw(g2);
			}
		}
		
		//Color currentFaceColor = faceColor;
		//Color currentFillColor = fillColor;
		Stroke currentStroke = g2.getStroke();
		
		if (isSelected()) {
			selectedDraw(g2);
		}
		
		//	 faceColor = currentFaceColor;
		// fillColor = currentFillColor;
		g2.setStroke(currentStroke);
	}
	
//	*****************************************************************************
	
	private void selectedDraw(Graphics2D g2){
		shape = new Polygon();
		LineDraw line = new LineDraw();
		
		for(int j=0;j<points.size();j++){
			((Polygon)shape).addPoint( ((Point)points.get(j)).x, ((Point)points.get(j)).y );
		}
		Color trans = new Color(0.0f,1.0f,1.0f,0.5f);
		g2.setPaint(trans);
		g2.fill(shape);
		g2.draw(shape);
		
		g2.setStroke(new BasicStroke(1.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
		g2.setColor( new Color(0.0f,1.0f,1.0f));
		for(int i=0;i<this.points.size();i++){
			if(i!=this.points.size()-1){
				line = new LineDraw ((Point)points.get(i),(Point)points.get(i+1));
			}else if(i==this.points.size()-1){
				line = new LineDraw ((Point)points.get(i),(Point)points.get(0));
			}
			line.draw(g2);
		}
		
	}
	
	
	/**
	 * Returns the draw bounds in device units.
	 *
	 * @return the draw bounds
	 */
	public Rectangle getBounds() {
		return shape.getBounds();
	}
	
//	*****************************************************************************
	
	public boolean contains(Point p) {
		double xCenter = shape.getBounds().getCenterX();
		double yCenter = shape.getBounds().getCenterY();
		
		double w = shape.getBounds().getWidth();
		double h = shape.getBounds().getHeight();
		
		if(w==0){
			w=h;
		}
		if(h==0){
			h=w;
		}
		if(w==0&&h==0){
			w=1;
			h=1;
		}
		
		Polygon shape = new Polygon();
		
		shape.addPoint((int)(xCenter-w*0.25),
				(int)(yCenter-h*0.25));
		shape.addPoint((int)(xCenter+w*0.25),
				(int)(yCenter-h*0.25));
		shape.addPoint((int)(xCenter+w*0.25),
				(int)(yCenter+h*0.25));
		shape.addPoint((int)(xCenter-w*0.25),
				(int)(yCenter+h*0.25));
		
		return shape.contains(p);
	}
	
//	*****************************************************************************
	
	public Color getFaceColor() {
		return faceColor;
	}
	
	public void setFaceColor(Color faceColor) {
		this.faceColor = faceColor;
	}
	
	public Color getFillColor() {
		return fillColor;
	}
	
	public void setFillColor(Color fillColor) {
		this.fillColor = fillColor;
	}
	
	public byte getFillType() {
		return fillType;
	}
	
	public void setFillType(byte fillType) {
		this.fillType = fillType;
	}
	
	public float getIntensity() {
		return intensity;
	}
	
	public void setIntensity(float intensity) {
		this.intensity = intensity;
	}
	
	public boolean isFillOn() {
		return isFillOn;
	}
	
	public void setFillOn(boolean isFill) {
		this.isFillOn = isFill;
	}
	
	public Float getLineWidth() {
		return lineWidth;
	}
	
	public void setLineWidth(Float lineWidth) {
		this.lineWidth = lineWidth;
	}
	
	public synchronized ArrayList getPoints() {
		return points;
	}
	
	public synchronized void setPoints(ArrayList points) {
		this.points.clear();
		this.points = points;
	}
	
	public boolean isBoundaryOn() {
		return isBoundaryOn;
	}
	
	public void setBoundaryOn(boolean isBoundaryOn) {
		this.isBoundaryOn = isBoundaryOn;
	}
	
//	*****************************************************************************
}
